package com.googlecode.garbagecan.test.socket.nio;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class MyServer1 {

	private final static Logger logger = Logger.getLogger(MyServer1.class.getName());
	
	public static void main(String[] args) throws IOException {
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		serverSocketChannel.socket().setReuseAddress(true);
		serverSocketChannel.socket().bind(new InetSocketAddress(10000));
		
		while (true) {
			SocketChannel socketChannel = serverSocketChannel.accept();
			invoke(socketChannel);
		}
	}

	private static void invoke(final SocketChannel socketChannel) throws IOException {
		new Thread(new Runnable() {
			public void run() {
				Socket socket = null;
				GZIPInputStream gzipis = null;
				ObjectInputStream ois = null;
				GZIPOutputStream gzipos = null;
				ObjectOutputStream oos = null;
				
				try {
					socket = socketChannel.socket();
					gzipis = new GZIPInputStream(socket.getInputStream());
					ois = new ObjectInputStream(gzipis);
					gzipos = new GZIPOutputStream(socket.getOutputStream());
					oos = new ObjectOutputStream(gzipos);

					Object obj = ois.readObject();
					MyRequestObject myRequestObject = (MyRequestObject)obj;
					logger.log(Level.INFO, myRequestObject.toString());
					
					MyResponseObject myResponseObject = new MyResponseObject(
							"response for " + myRequestObject.getName(), 
							"response for " + myRequestObject.getValue());
					oos.writeObject(myResponseObject);
					oos.flush();
					gzipos.finish();
				} catch (IOException ex) {
					logger.log(Level.SEVERE, null, ex);
				} catch(ClassNotFoundException ex) {
					logger.log(Level.SEVERE, null, ex);
				} finally {
					try {
						ois.close();
					} catch(Exception ex) {}
					try {
						oos.close();
					} catch(Exception ex) {}
					try {
						socket.close();
					} catch(Exception ex) {}
					try {
						socketChannel.close();
					} catch(Exception ex) {}
				}
			}
		}).start();
	}
}
